package com.example.springboot.utils.task;

import com.wbs.utls.vo.MQRestRstDta;
import com.wbs.utls.vo.ResponseResultVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程池，默认30个线程
 *
 * @author wangsh
 * @date 2019/8/8 21:16
 * @Description
 */
public class ThreadUtils {

    public static final Logger log = LoggerFactory.getLogger(ThreadUtils.class);
    //线程池大小
    private static int POOL_SIZE = 10;
    //最大线程数
    private static int MAX_POOL_SIZE = 30;
    //    存活时间，默认5秒
    private static int KEEP_ALIVE_TIME = 5;
    //队列大小
    private static int Block_QUEUE_SIZE = 5;

    private static ThreadPoolExecutor executorService = null;

    private static String fileName = "application.properties";
    private static Lock lock = new ReentrantLock();

    static {
        try {
            InputStream instream = ThreadUtils.class.getClassLoader().getResourceAsStream(fileName);
            Properties prop = new Properties();
            prop.load(instream);
            Object poolSize = prop.get("poolSize");
            if (poolSize != null && !"".equals(poolSize)) {
                POOL_SIZE = Integer.parseInt(poolSize.toString());
            }
            Object maxPoolSize = prop.get("maxPoolSize");
            if (maxPoolSize != null && !"".equals(maxPoolSize)) {
                MAX_POOL_SIZE = Integer.parseInt(maxPoolSize.toString());
            }
            Object keepAliveTime = prop.get("keepAliveTime");
            if (keepAliveTime != null && !"".equals(keepAliveTime)) {
                KEEP_ALIVE_TIME = Integer.parseInt(keepAliveTime.toString());
            }

            Object blockQueueSize = prop.get("blockQueueSize");
            if (blockQueueSize != null && !"".equals(blockQueueSize)) {
                Block_QUEUE_SIZE = Integer.parseInt(blockQueueSize.toString());
            }
            executorService = new ThreadPoolExecutor(POOL_SIZE, MAX_POOL_SIZE,
                    KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(Block_QUEUE_SIZE));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    public static ThreadPoolExecutor getThreadPool() {
//
//        lock.lock();
//        try {
//            //默认创建30个线程
//            if (executorService == null) {
//                executorService = new ThreadPoolExecutor(POOL_SIZE, MAX_POOL_SIZE,
//                        KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(Block_QUEUE_SIZE));
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            lock.unlock();
//        }
        return executorService;
    }

    public static void main(String[] args) {

        ThreadPoolExecutor threadPool = ThreadUtils.getThreadPool();


//          public ScheduledThreadPoolExecutor(int corePoolSize) {
//            super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
//                    new DelayedWorkQueue());
//        }
//


        threadPool.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("测试submit线程池： " + POOL_SIZE);
            }
        });


        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("测试execute线程池： " + POOL_SIZE);
            }
        });
        threadPool.shutdown();

        threadPool = ThreadUtils.getThreadPool();

        //对于数据缓存REDIS和发送MQ不需要同步操作时，可用此方法进行处理，返回操作的结果
        Future<MQRestRstDta<ResponseResultVo>> future = threadPool.submit(new Callable<MQRestRstDta<ResponseResultVo>>() {
            @Override
            public MQRestRstDta<ResponseResultVo> call() {
                ResponseResultVo vo = new ResponseResultVo();
                vo.setMsg("123");
                vo.setStatus(true);
                vo.setResult(true, "123");
                MQRestRstDta<ResponseResultVo> mQRestRstDta = new MQRestRstDta<>(1, vo);
                return mQRestRstDta;
            }
        });

        try {
            MQRestRstDta<ResponseResultVo> o = future.get();
            ResponseResultVo result = o.getResult();
            Integer count = o.getCount();
            String msg = result.getMsg();
            boolean status = result.getStatus();
            log.info("o:{}  result:{}  count:{}  msg:{}  status:{}", o, result, count, msg, status);

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        threadPool.shutdown();
    }
}
